<!-- EditableTable.vue -->
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import {
    Edit,
    Delete,
    Check,
    CloseBold
} from '@element-plus/icons-vue'

// 定义列类型
interface Column {
    label: string
    prop: string
    type: 'text' | 'select'
    options?: { label: string; value: any }[]
    required?: boolean // 👈 新增字段
}

// Props
const props = defineProps<{
    columns: Column[]
    modelValue: any[] // 所有数据（含新增行）
    total: number // 总条数（后端提供）
    currentPage: number
    pageSize: number
    loading?: boolean
}>()

// Emits
const emit = defineEmits<{
    (e: 'update:modelValue', value: any[]): void
    (e: 'edit', row: any): void
    (e: 'save', row: any, index: number): void
    (e: 'delete', row: any, index: number): void
    (e: 'add', row: any, index: number): void
    (e: 'cancel', row: any | null, index: number): void
    (e: 'load-data', page: number, size: number): void // 请求数据
}>()

// 本地数据副本（仅当前页 + 新增行）
const tableData = ref<any[]>([])

// 同步 modelValue 到 tableData（响应式引用）
watch(
    () => props.modelValue,
    (newVal) => {
        tableData.value = newVal
    },
    { deep: true, immediate: true }
)

// 分页相关
const localCurrentPage = ref(props.currentPage)
const localPageSize = ref(props.pageSize)

// 监听 props 的 current-page 和 page-size
watch(
    () => props.currentPage,
    (val) => {
        localCurrentPage.value = val
    }
)
watch(
    () => props.pageSize,
    (val) => {
        localPageSize.value = val
    }
)

// 获取 select 显示 label
const getLabelByValue = (options: { label: string; value: any }[], value: any): string => {
    const item = options.find((o) => o.value === value)
    return item ? item.label : ''
}

// 编辑事件
const handleEdit = (row: any) => emit('edit', row)
const handleSave = (row: any, index: number) => {
    if (!validateRow(row, props.columns)) return
    emit('save', row, index)
}
const handleDelete = (row: any, index: number) => emit('delete', row, index)
const handleCancel = (row: any, index: number) => emit('cancel', row, index)

// 新增按钮点击
const handleAdd = () => {
    const newRow: any = {}
    props.columns.forEach((col) => {
        newRow[col.prop] = ''
    })
    newRow._editing = true
    newRow._isNew = true
    tableData.value.unshift(newRow)
    updateModelValue()
}

// 确认新增
const handleConfirmAdd = (row: any, index: number) => {
    console.log("handleConfirmAdd", row, index)
    if (!validateRow(row, props.columns)) return
    emit('add', row, index)
    updateModelValue()
}
// 取消新增
const handleCancelAdd = (index: number) => {
    tableData.value.splice(index, 1)
    emit('cancel', null, index)
    updateModelValue()
}

// 更新 modelValue
const updateModelValue = () => {
    emit('update:modelValue', [...tableData.value])
}

// 计算当前页显示的数据（考虑新增行）
const displayedData = computed(() => {
    const newRows = tableData.value.filter(row => row._isNew)
    const paginatedRows = tableData.value
        .filter(row => !row._isNew)
        .slice((localCurrentPage.value - 1) * localPageSize.value, localCurrentPage.value * localPageSize.value)

    return [...newRows, ...paginatedRows]
})

// 处理输入框变化
const handleInput = (val: string, row: any, prop: string) => {
    row[prop] = val
    updateModelValue()
}

// 分页大小改变
const handleSizeChange = (size: number) => {
    localPageSize.value = size
    emit('load-data', 1, size)
}

// 当前页改变
const handleCurrentChange = (page: number) => {
    localCurrentPage.value = page
    emit('load-data', page, localPageSize.value)
}

const validateRow = (row: any, columns: Column[]) => {
    for (const col of columns) {
        if (col.required && !row[col.prop]) {
            ElMessage.warning(`${col.label} 是必填项`)
            return false
        }
    }
    return true
}
</script>

<template>
    <el-table :data="displayedData" border style="width: 100%" :loading="loading">
        <!-- 动态列渲染 -->
        <el-table-column v-for="(col, index) in columns" :key="index" :prop="col.prop">
            <template #header>
                <span v-if="col.required" style="color: red; margin-right: 4px;">*</span>
                <span>{{ col.label }}</span>
            </template>
            <template #default="scope">
                <div v-if="col.type === 'text'">
                    <span v-if="!scope.row._editing">{{ scope.row[col.prop] }}</span>
                    <el-input v-else :model-value="scope.row[col.prop]"
                        @update:model-value="val => handleInput(val, scope.row, col.prop)" />
                </div>

                <div v-else-if="col.type === 'select'">
                    <span v-if="!scope.row._editing">
                        {{ getLabelByValue(col.options || [], scope.row[col.prop]) }}
                    </span>
                    <el-select v-else :model-value="scope.row[col.prop]"
                        @update:model-value="val => handleInput(val, scope.row, col.prop)" placeholder="请选择"
                        style="width: 100%">
                        <el-option v-for="item in col.options" :key="item.value" :label="item.label"
                            :value="item.value" />
                    </el-select>
                </div>
            </template>
        </el-table-column>

        <!-- 操作列 -->
        <el-table-column label="操作" width="120">
            <template #default="scope">
                <div v-if="!scope.row._isNew">
                    <el-button v-if="!scope.row._editing" type="text" @click="handleEdit(scope.row)">
                        <el-icon>
                            <Edit />
                        </el-icon>
                    </el-button>
                    <el-button v-else type="text" @click="handleSave(scope.row, scope.$index)">
                        <el-icon>
                            <Check />
                        </el-icon>
                    </el-button>

                    <el-button v-if="!scope.row._editing" type="text" @click="handleDelete(scope.row, scope.$index)">
                        <el-icon>
                            <Delete />
                        </el-icon>
                    </el-button>
                    <el-button v-else type="text" @click="handleCancel(scope.row, scope.$index)">
                        <el-icon>
                            <CloseBold />
                        </el-icon>
                    </el-button>
                </div>

                <div v-else>
                    <el-button type="text" @click="handleConfirmAdd(scope.row, scope.$index)">
                        <el-icon>
                            <Check />
                        </el-icon>
                    </el-button>
                    <el-button type="text" @click="handleCancelAdd(scope.$index)">
                        <el-icon>
                            <CloseBold />
                        </el-icon>
                    </el-button>
                </div>
            </template>
        </el-table-column>
    </el-table>

    <el-pagination layout="total, prev, pager, next, sizes, jumper" :total="total" :page-size="localPageSize"
        :current-page="localCurrentPage" @size-change="handleSizeChange" @current-change="handleCurrentChange"
        style="margin-top: 16px" />

    <el-button @click="handleAdd" style="margin-top: 16px">新增</el-button>
</template>